#include "base/channel.h"
#include "base/channelpool.h"
#include "base/log.h"

#include "base/epoll.h"
namespace net_tools::base{

Epoll::Epoll(int size,std::atomic<bool>* wakeup)
  :channelpool_(new Channelpool(this,size)),
   epollid_(epoll_create(2048)),
   wakeup_(wakeup),
   max_event_number_(size),
   last_time_triggered_(0)
{
  epoll_event_.reserve(size);
};
void Epoll::Epoll_wait(int time_out){
  wakeup_->store(false);
  last_time_triggered_ = epoll_wait(epollid_,
                                  &*epoll_event_.begin(),
                                    max_event_number_,
                                    time_out);
  wakeup_->store(true);
  for(int count = 0;count < last_time_triggered_;++count){
    reinterpret_cast<Channel*>(epoll_event_[count].data.ptr)
                  ->Callback(epoll_event_[count].events);
  }
  if(last_time_triggered_ == max_event_number_) [[unlikely]] {
    max_event_number_  = max_event_number_ << 1;
    epoll_event_.reserve(max_event_number_);
  }
};
void Epoll::Add_event(Channel *channel_){
  // NT_LOG_INFO << channel_ << NT_LOG_ENDL;
  epoll_ctl(epollid_, EPOLL_CTL_ADD, channel_->listenfd_, &channel_->event_);
};
void Epoll::Mod_event(Channel *channel_){
  epoll_ctl(epollid_, EPOLL_CTL_MOD, channel_->listenfd_, &channel_->event_);
};
void Epoll::Del_event(Channel *channel_){
  epoll_ctl(epollid_, EPOLL_CTL_DEL, channel_->listenfd_, &channel_->event_);
};
Channel* Epoll::Get_free_channel(int fd){
  return channelpool_->Get_Channel(fd);
};
void Epoll::Free_channel(Channel* channel){
  channelpool_->Free_Channel(channel);
};

} // namespace net_tools::base